#!/usr/bin/python3
import os
import re
import json
import shutil
from obs import OpensuseObsAPI
from settings import INSTALL_PACKAGE_PATH
from base import recursivedict


class InstallRequires:
    """
    安装依赖的获取
    """

    def __init__(self, arch="aarch64") -> None:
        self._obs = OpensuseObsAPI()
        self._arch = arch
        self.result = recursivedict()
        self._project = None

    def _successed(self, build_result):
        if not build_result:
            return False
        for _, status in build_result[self._arch].items():
            if status != "succeeded":
                return False
        return True

    def _checked_install(self, package):
        check_install = os.path.join(INSTALL_PACKAGE_PATH, "check-install")
        check_log = os.path.join(INSTALL_PACKAGE_PATH, "logs")
        os.makedirs(check_log, exist_ok=True)
        if os.system("bash check-install.sh %s %s" % (check_install, check_log)) != 0:
            raise RuntimeError("An error occurred while verifying the installation")

        # 提取每个软件包编译的结果
        for file in os.listdir(check_log):
            if not file.endswith(".log") or package not in file:
                continue
            provides = self._extract_provide(file=os.path.join(check_log, file))
            if provides:
                self.result[package]["install"]["status"] = "failed"
                self.result[package]["install"]["provides"] = provides

            else:
                self.result[package]["install"]["status"] = "succeeded"
            break
        try:
            shutil.rmtree(check_install, ignore_errors=True)
            shutil.rmtree(check_log, ignore_errors=True)
        except IOError:
            pass

    def _extract_provide(self, file):
        if not os.path.exists(file):
            return []
        with open(file, "r", encoding="utf-8") as f:
            return re.findall(".*nothing provides(.*) needed.*", f.read())

    def _write_result(self, file):
        if os.path.exists(file):
            os.remove(file)
        with open(file, "w", encoding="utf-8") as f:
            f.write(json.dumps(self.result))

    def _build_requires(self, build_result):
        if not build_result:
            raise ValueError(
                "The installation verification fails because the software "
                "package is not compiled successfully "
            )
        unresolvable_packages = self._obs.get_unresolvable(project_name=self._project)
        for package, status in build_result[self._arch].items():
            self.result[package]["build"]["status"] = status
            try:
                if status == "unresolvable":
                    self.result[package]["build"]["provides"] = unresolvable_packages[
                        package
                    ]
            except (TypeError, KeyError):
                self.result[package]["build"]["provides"] = []

    def install(self, project, csv_file=None, package=None):
        """
        obs工程下的rpm包安装校验
        """
        self._project = project
        build_result = self._obs.get_package_status(project=project, package=package)
        try:
            # Compile dependent packages
            self._build_requires(build_result=build_result)
        except ValueError:
            return {
                project: {
                    "note": "The project does not exist or an error occurred during compilation"
                }
            }

        for pkg in self.result.keys():

            if self.result[pkg]["build"]["status"] != "succeeded":
                continue

            # 下载rpm包
            binary_package = self._obs.published_packages(project=project, package=pkg)
            if not binary_package:
                self.result[pkg]["note"][
                    "binary-not-found"
                ] = "The binary RPM package corresponding to the current software package is not found"
                continue
            if not self._obs.download_binary_file(
                project=project, package=pkg, binary_name=binary_package
            ):
                self.result[pkg]["note"]["download-failed"] = (
                    "Downloading the binary packet %s failed " % binary_package
                )
                continue
            try:
                # 执行安装验证
                self._checked_install(package=pkg)
            except RuntimeError:
                self.result[pkg]["note"][
                    "check-install-error"
                ] = "An error occurred while verifying the installation"
        if csv_file is None:
            csv_file = os.path.join(INSTALL_PACKAGE_PATH, project + ".json")

        self._write_result(file=csv_file)


if __name__ == "__main__":
    p = recursivedict()
    packages = [
        "sonatqube",
        "springfrawork",
        "react",
        "shiro",
        "solr",
        "mozjs",
        "OpenFOAM",
        "ltp",
        "minio",
        "VUE",
        "iscsi-initiator-utils-iscsiuio",
        "Lammps",
        "controller-manager",
        "ingresscontroller",
        "kubelet",
        ".NetCore",
        "blackbox_exporter",
        "brpc",
        "dbeaver",
        "gatk",
        "gerrit",
        "glassfish",
        "home-assistant",
        "janusgraph",
        "mitmproxyNA",
        "mozjs",
        "openhpc",
        "swagger",
        "tdengineLatest",
        "tez",
        "tornado",
        "webhook",
        "wildfly",
        "zeppelin",
        "zeronet",
        "audit-libs-python",
        "clickhouse",
        "pd-server",
        "isa-l",
        "alluxio",
        "accumulo",
        "mongoose",
        "hue",
        "zeppelin",
        "phoenix",
        "tdengine",
        "lstio",
        "ats",
        "sqoop",
    ]
    for pkg in packages:
        project = "home:gongzt:" + pkg
        _install = InstallRequires()
        result = _install.install(project=project, package=pkg)
        p.update(result)

    with open("/home/gzt/result.json", "w", encoding="utf-8") as f:
        f.write(json.dumps(p))
